BUILDPATH = build
DEBUG = HIGH
GDBTUI = FALSE
AS = nasm
ASFLAGS = -f elf32 -I .
CC = gcc
CFLAGS = -m32 -I . -c -fno-builtin -fno-stack-protector
LD = ld
LDFLAGS = -m elf_i386 -T kernel.lds -e main
DBG = gdb
DBGFLAGS =
ifeq ($(DEBUG), TRUE)
	ASFLAGS += -g -F stabs
	CFLAGS += -g
endif
ifeq ($(DEBUG), HIGH)
	ASFLAGS += -g -F stabs
	CFLAGS += -g3
endif
ifeq ($(GDBTUI), TRUE)
	DBGFLAGS += -tui
endif
OBJS = $(BUILDPATH)/main.o $(BUILDPATH)/init.o $(BUILDPATH)/memctrl.o $(BUILDPATH)/bitmap.o $(BUILDPATH)/memory.o $(BUILDPATH)/print.o $(BUILDPATH)/intrentry.o $(BUILDPATH)/interrupt.o $(BUILDPATH)/timer.o $(BUILDPATH)/format.o $(BUILDPATH)/thread.o

.PHONY : help init all allgdb allddd build load run rungdb runddd clean

help:
	@echo "本目录下的 make help 如下:"
	@echo "make all -- 依次完成 init build load run"
	@echo "make allgdb -- 依次完成 init build load rungdb"
	@echo "make allddd -- 依次完成 init build load runddd"
	@echo "make init -- 初始化build目录，需要首先进行该命令"
	@echo "make clean -- 清理build目录下的全部文件"
	@echo "make build -- 编译引导程序和内核程序, 是否开启DEBUG模式取决于DEBUG关键字是否被重定义"
	@echo "make load -- 将程序加载到虚拟磁盘中"
	@echo "make run -- 在bochs虚拟机中运行程序"
	@echo "make rungdb -- 在bochs-gdb中运行程序, 使用gdb远程调试c语言代码, 仅在DEBUG模式使用"
	@echo "make runddb -- 在bochs-gdb中运行程序, 使用gdb远程调试c语言代码, 并使用ddd作为其前端, 仅在DEBUG模式使用"
	@echo "!!! 特别注意 !!!"
	@echo "!!! build指令默认开启debug模式，供gdb和ddd使用, 可以使用选项DEBUG=0来关闭 !!!"
	@echo "!!! ddd模式不支持中文，因此若要使用ddd调试，请不要在代码中包括中文 !!!"
	@echo "!!! 如果想要使用gdb的tui模式，请加入开关GDBTUI=TRUE !!!"

all: clean build load run

allgdb: clean build load rungdb

allddd: clean build load runddd

init: 
	test -d $(BUILDPATH) || mkdir $(BUILDPATH)

clean:
	rm -rf $(BUILDPATH)/*

build: $(BUILDPATH)/kernel.bin $(BUILDPATH)/loader.bin $(BUILDPATH)/mbr.bin

load: 
	dd if=/dev/zero of=hd100M.img bs=512 count=300 seek=0 conv=notrunc
	dd if=$(BUILDPATH)/mbr.bin of=hd100M.img bs=512 count=1 seek=0 conv=notrunc	
	sudo mount hd100M.img disk/ -t msdos -o loop
	sudo cp $(BUILDPATH)/loader.bin disk
	sudo cp $(BUILDPATH)/kernel.bin disk
	sync
	sudo umount disk

run:
	bochs -f bochsrc.txt

rungdb:
	gnome-terminal -- bash -c "bochs-gdb -q -f bochsrc_gdb.txt"
	$(DBG) $(DBGFLAGS) $(BUILDPATH)/kernel.bin

runddd:
	gnome-terminal -- bash -c "bochs-gdb -q -f bochsrc_gdb.txt"
	ddd $(BUILDPATH)/kernel.bin

$(BUILDPATH)/loader.bin:
	$(AS) boot/loader.S -I . -o $(BUILDPATH)/loader.bin

$(BUILDPATH)/mbr.bin: boot/mbr.S
	$(AS) boot/mbr.S -I . -o $(BUILDPATH)/mbr.bin

$(BUILDPATH)/kernel.bin: $(OBJS)
	$(LD) $(LDFLAGS) $^ -Ttext 0xc0010000 -o $@

$(BUILDPATH)/main.o: kernel/main.c
	$(CC) $(CFLAGS) $< -o $@

$(BUILDPATH)/init.o: kernel/init.c
	$(CC) $(CFLAGS) $< -o $@

$(BUILDPATH)/memctrl.o: lib/memctrl.S
	$(AS) $(ASFLAGS) $< -o $@

$(BUILDPATH)/bitmap.o: memory/bitmap.c
	$(CC) $(CFLAGS) $< -o $@

$(BUILDPATH)/memory.o: memory/memory.c
	$(CC) $(CFLAGS) $< -o $@

$(BUILDPATH)/print.o: lib/print.S
	$(AS) $(ASFLAGS) $< -o $@

$(BUILDPATH)/format.o: lib/format.c
	$(CC) $(CFLAGS) $< -o $@

$(BUILDPATH)/intrentry.o: interrupt/intrentry.S
	$(AS) $(ASFLAGS) $< -o $@

$(BUILDPATH)/interrupt.o: interrupt/interrupt.c
	$(CC) $(CFLAGS) $< -o $@

$(BUILDPATH)/timer.o: device/timer.c
	$(CC) $(CFLAGS) $< -o $@

$(BUILDPATH)/thread.o: thread/thread.c
	$(CC) $(CFLAGS) $< -o $@